package com.whoyx.jiebing.config;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Optional;

/**
 * @author stone
 */
@Slf4j
@Component
@Aspect
public class LogAspect {

    @Around("execution(* com.whoyx.jiebing.controller..*.*(..)) ")
    public Object handleControllerMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //原始的HTTP请求和响应的信息
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        HttpServletRequest request = attributes.getRequest();
        Signature signature = proceedingJoinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature)signature;
        //获取当前执行的方法
        Method targetMethod = methodSignature.getMethod();
        //获取参数
        Object[] objects = proceedingJoinPoint.getArgs();
        StringBuilder params = new StringBuilder();
        String dot = ",";
        if (null != objects && objects.length > 0) {
            Arrays.asList(objects).forEach(object -> {
                boolean isRequest = object instanceof ServletRequest || object instanceof MultipartFile;
                if (!isRequest) {
                    params.append(JSONUtil.toJsonStr(object)).append(dot);
                }
            });
        }
        if (params.toString().endsWith(dot)) {
            params.deleteCharAt(params.length() - 1);
        }
        //获取返回对象
        Object object = null;
        try {
            object = proceedingJoinPoint.proceed();
        } finally {
            String sb =
                    "\n-------------------------------------------------------------\n" +
                    "Controller: " + targetMethod.getDeclaringClass().getName() + "\n" +
                    "Method    : " + targetMethod.getName() + "\n" +
                    "Params    : " + params + "\n" +
                    "URI       : " + request.getRequestURI() + "\n" +
                    "URL       : " + request.getRequestURL() + "\n" +
                    "Return    : " + Optional.ofNullable(object).map(JSONUtil::toJsonStr).orElse("") +
                    "\n-------------------------------------------------------------\n";
            log.info("\n【请求参数】参数：{}", sb);
        }
        return object;
    }


}
